home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / games / ippon / source.lzh / eshot.c < prev    next >
C/C++ Source or Header  |  2000-07-07  |  6KB  |  225 lines

  1. /* eshot.c */
  2.  
  3. #include <stdio.h>
  4. #include <xsp2lib.h>
  5.  
  6. #include "main.h"
  7. #include "player.h"
  8. #include "eshot.h"
  9.  
  10. #define    PALET_ESHOT    0x0300
  11.  
  12. #define ESHOT_MAX    200    /* 敵弾最大数 */
  13. static ESHOT eshot[ESHOT_MAX];    /* ワーク */
  14.  
  15.  
  16.  
  17. /* ゲーム開始時に呼ばれる */
  18. void EshotInit (void)
  19. {
  20.     int i;
  21.  
  22.     /* リストをつなげる */
  23.     eshot_top = NULL;
  24.     eshot_null_top = eshot;
  25.     for (i = 0; i < ESHOT_MAX; i++)
  26.         eshot[i].next = &eshot[i + 1];
  27.  
  28.     eshot[ESHOT_MAX - 1].next = NULL;
  29. }
  30.  
  31.  
  32.  
  33. /* 敵弾出現時に呼ばれる */
  34. void EshotAlloc (short type, signed short x, signed short y, unsigned char speed, unsigned char angle, signed short t)
  35. {
  36.     ESHOT *p;
  37.  
  38.     if (eshot_null_top == NULL)    /* ワークの空きはあるか? */
  39.         return;
  40.  
  41.     p = eshot_null_top;
  42.     eshot_null_top = p->next;
  43.     p->next = eshot_top;
  44.     eshot_top = p;
  45.  
  46.     p->lx = (x - 8) << 16;    /* (8,8) がスプライト座標の中心なので補正 */
  47.     p->ly = (y - 8) << 16;
  48.     p->vx = xytable[speed][angle].x;
  49.     p->vy = xytable[speed][angle].y;
  50.     if (t) {        /* t フレーム後の値を初期値に */
  51.         p->lx += (p->vx * t);
  52.         p->ly += (p->vy * t);
  53.     }
  54.     /* メモ:敵弾の速度と当り判定の大きさについて */
  55.     /* eshot->hx が以下の場合、eshot->vx の最大値は以下の通り */
  56.     /* (hx,vx 未満) = (2,1.0),(3,3.0),(4,5.0),(5,7.0),(6,9.0) */
  57.     /* 算出式は以下の通り */
  58.     /* eshot->vx+player->vx > 2*eshot->hx の時判定抜けが発生 */
  59.     /* player->vx の最大値は 3.0(高速移動時) */
  60.  
  61.     switch (p->type = type) {
  62.     case ESHOT_NRG01:    /* エネルギー弾(極小) */
  63.         p->hit_p = 2;    /* 速度を 1.0 未満にする事 */
  64.         p->pt = sp_eshot + type;
  65.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  66.         break;
  67.  
  68.     case ESHOT_NRG02:    /*    〃   (小) */
  69.     case ESHOT_NRG03:    /*    〃   (中) */
  70.     case ESHOT_NRG04:    /*    〃   (大) */
  71.         p->hit_p = 3;    /* 速度を 3.0 未満にする事 */
  72.         p->pt = sp_eshot + type;
  73.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  74.         break;
  75.  
  76.     case ESHOT_NRG05:    /*    〃   (特大) */
  77.     case ESHOT_NRG06:    /*    〃   (特大) */
  78.     case ESHOT_NRG22:    /*    〃   (小横に2個) */
  79.     case ESHOT_NRG32:    /*    〃   (中横に2個) */
  80.     case ESHOT_NRG23:    /*    〃   (小3角形に3個) */
  81.     case ESHOT_NRG24:    /*    〃   (小正方形に4個) */
  82.     case ESHOT_NRG14N:    /*    〃   (小斜めに4個) */
  83.     case ESHOT_NRG24N:    /*    〃   (中斜めに4個) */
  84.     case ESHOT_NRG34N:    /*    〃   (中斜めに4個) */
  85.     case ESHOT_NRG34:    /*    〃   (中正方形に4個) */
  86.     case ESHOT_NRG15:    /*    〃   (小5個) */
  87.     case ESHOT_NRG35:    /*    〃   (小と大正方形に5個) */
  88.         p->hit_p = 4;    /* 速度を 5.0 未満にする事 */
  89.         p->pt = sp_eshot + type;
  90.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  91.         break;
  92. #if    0
  93.     case ESHOT_LASER01:
  94.         p->hit_p = 3;    /* 速度を 3.0 未満にする事 */
  95.         p->pt = sp_laser + 8;
  96.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  97.         break;
  98.  
  99.     case ESHOT_LASEREX:
  100.         p->hit_p = 4;    /* 速度を 5.0 未満にする事 */
  101.         p->pt = sp_laser + 9;
  102.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  103.         break;
  104. #endif
  105.     default:
  106.         break;
  107.     }
  108.  
  109. }
  110.  
  111.  
  112.  
  113. /* 垂直同期ごとに呼ばれる */
  114. void EshotMove (void)
  115. {
  116.     ESHOT *p, *q;
  117.     signed short pl_x = player->x - 8, pl_y = player->y - 8;
  118.  
  119. #ifdef DEBUG
  120.     eshot_sum = 0;
  121. #endif
  122.     p = eshot_top;        /* 現在注目しているワーク */
  123.     q = NULL;        /* 1つ前のワーク(ワーク削除時に必要) */
  124.  
  125.     /* 弾消し中か?(高速化のためやや冗長なコードになってます) */
  126.     if (eshot_erase == 0) {
  127.         /* 通常の処理(弾消しではない) */
  128.         while (p != NULL) {
  129.             signed short p_x, p_y;
  130.  
  131. #ifdef DEBUG
  132.             eshot_sum++;
  133. #endif
  134.             /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  135.             p_x = p->x = (p->lx += p->vx) >> 16;
  136.             p_y = p->y = (p->ly += p->vy) >> 16;
  137.  
  138.             /* 敵弾が画面外に出たか? */
  139.             /* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
  140.             if (((unsigned short) p_x > 256 + 16) || ((unsigned short) p_y > 256 + 16)) {
  141.                 /* 敵弾が画面外へ出たので消去 */
  142.                 if (q == NULL) {    /* リストの一番最初を削除 */
  143.                     eshot_top = p->next;
  144.                     p->next = eshot_null_top;
  145.                     eshot_null_top = p;
  146.                     q = NULL;
  147.                     p = eshot_top;
  148.                 } else {
  149.                     q->next = p->next;
  150.                     p->next = eshot_null_top;
  151.                     eshot_null_top = p;
  152.                     p = q->next;
  153.                 }
  154.             } else {
  155.                 /* 画面外へ出ていない時 */
  156.  
  157.                 /* 敵弾と自機の当たり判定 */
  158.                 /* この辺の最適化は -fstrings-reduce が頑張ってくれるハズ */
  159.                 signed short t, t2 = p->hit_p;
  160.                 if (((t = p_y - t2) <= pl_y)
  161.                     && ((t += (short) (t2 << 1)) >= pl_y)
  162.                     && ((t = p_x + t2) >= pl_x)
  163.                     && ((t -= (short) (t2 << 1)) <= pl_x)) {
  164.                     if ((player->status == PLAYER_STATUS_ALIVE) && (player->muteki == 0))
  165.                         player->status = PLAYER_STATUS_DEAD;
  166.                 } else {
  167.                     xsp_set_st (p);
  168.                 }
  169.  
  170.                 q = p;
  171.                 p = p->next;
  172.             }
  173.         }
  174.     } else {
  175.         /* 弾消し中 */
  176.         char erase_flag;    /* キャラクターを消す場合 =!0 */
  177.         unsigned short erase_table[14] =
  178.         {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6};
  179.  
  180.         while (p != NULL) {
  181.             signed short p_x, p_y;
  182.  
  183.             if (eshot_erase > 1)
  184.                 erase_flag = 0;
  185.             else
  186.                 erase_flag = !0;
  187. #ifdef DEBUG
  188.             eshot_sum++;
  189. #endif
  190.             /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  191.             p_x = p->x = (p->lx += p->vx) >> 16;
  192.             p_y = p->y = (p->ly += p->vy) >> 16;
  193.  
  194.             /* 敵弾が画面外に出たか? */
  195.             /* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
  196.             if (((unsigned short) p_x > 256 + 16) || ((unsigned short) p_y > 256 + 16))
  197.                 erase_flag = !0;
  198.  
  199.             if (erase_flag) {
  200.                 /* 敵弾が画面外へ出たので消去 */
  201.  
  202.                 if (q == NULL) {    /* リストの一番最初を削除 */
  203.                     eshot_top = p->next;
  204.                     p->next = eshot_null_top;
  205.                     eshot_null_top = p;
  206.                     q = NULL;
  207.                     p = eshot_top;
  208.                 } else {
  209.                     q->next = p->next;
  210.                     p->next = eshot_null_top;
  211.                     eshot_null_top = p;
  212.                     p = q->next;
  213.                 }
  214.             } else {
  215.                 p->pt = sp_eshotera + erase_table[eshot_erase];
  216.                 xsp_set_st (p);
  217.  
  218.                 q = p;
  219.                 p = p->next;
  220.             }
  221.         }
  222.         eshot_erase--;
  223.     }
  224. }
  225.